import 'dart:async';
import 'dart:io';

import 'package:flutter_benchu/utils/commonPkg.dart';
import 'package:path_provider/path_provider.dart';
import 'package:rxdart/rxdart.dart';

/// Log Util.
class Log {
  static const String _TAG_DEF = "###APP###";
  static String defaultTag = _TAG_DEF;
  static File _file;
  static PublishSubject _sub = PublishSubject();

  static Future<void> init({String tag = _TAG_DEF}) async {
    if (!envs.openLog) {
      return;
    }
    defaultTag = tag;
    var tempDir = await getApplicationSupportDirectory();
    String tempPath = tempDir.path;
    _file = File(
      '$tempPath/log.log',
    );
    if (!await _file.exists()) {
      _file.createSync();
    }
    _sub.stream.asyncMap((str) async {
      await _writeLocalFile(str);
    }).listen((_) {});
  }

  static void e(Object object, {String tag}) {
    if (!envs.openLog) {
      return;
    }
    _printLog(tag, '  e  ', object);
  }

  static void v(Object object, {String tag}) {
    if (!envs.openLog) {
      return;
    }
    _printLog(tag, '  v  ', object);
  }

  static void _printLog(String tag, String stag, Object object) async {
    String da = object.toString();
    String _tag = (tag == null || tag.isEmpty) ? defaultTag : tag;
    if (da.length > 1024 * 1024 * 0.5) {
      return;
    }
    while (da.isNotEmpty) {
      if (da.length > 512) {
        print("$_tag $stag ${da.substring(0, 512)}");
        _sub.sink.add('$_tag $stag ${da.substring(0, 512)}');
        da = da.substring(512, da.length);
      } else {
        print("$_tag $stag $da");
        _sub.sink.add("$_tag $stag $da");
        da = "";
      }
    }
  }

  static _writeLocalFile(log) async {
    try {
      await _file.writeAsString('\n$log\n', mode: FileMode.append, flush: true);
    } catch (err) {
      print(err);
    }
  }

  static Future<String> readLocalFile() async {
    if (!envs.openLog) {
      return '';
    }
    try {
      String str = await _file.readAsString();
      return str;
    } catch (err) {
      print(err);
      return '';
    }
  }

  static Future<void> delLocalFile() async {
    if (!envs.openLog) {
      return;
    }
    try {
      await _file.delete();
      _file.createSync();
    } catch (err) {
      print(err);
    }
  }

  static void dispose() {
    if (!envs.openLog) {
      return;
    }
    _sub.close();
  }
}
